package cn.mujiankeji.mbrowser.界面.标签页.快照

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.unit.dp
import cn.mujiankeji.mbrowser.工具.JSON
import cn.mujiankeji.mbrowser.工具.mlog
import com.google.gson.Gson
import cn.mujiankeji.mbrowser.数据.快照来源.快照来源接口
import cn.mujiankeji.mbrowser.数据.快照来源.快照源_列表
import cn.mujiankeji.mbrowser.数据.数据库.AppDatabase
import cn.mujiankeji.mbrowser.数据.数据库.DBQzm
import cn.mujiankeji.mbrowser.数据.枚举类.快照类型枚举
import cn.mujiankeji.mbrowser.界面.图标.MyIconPack
import cn.mujiankeji.mbrowser.界面.图标.myiconpack.保存
import cn.mujiankeji.mbrowser.界面.图标.myiconpack.更多
import cn.mujiankeji.mbrowser.界面.标签页.统一标签页布局
import cn.mujiankeji.mbrowser.界面.框架.主视图.标签页状态
import cn.mujiankeji.mbrowser.界面.组件.布局.项目卡片
import cn.mujiankeji.mbrowser.界面.组件.配置列表.配置行_开关
import cn.mujiankeji.mbrowser.界面.组件.配置列表.配置行_选项
import com.blankj.utilcode.util.GsonUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import 界面.弹窗.下拉菜单
import 界面.弹窗.下拉菜单项目
import kotlinx.serialization.SerialName
import org.koin.core.context.GlobalContext
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.findAnnotations

/**
 * @param bid 订阅包 uuid
 */
class 快照编辑页面状态(val mEditId : Long = 0L,val bid : String = "") : 标签页状态() {

    var coroutine : CoroutineScope ?= null

    val 编辑数据 = mutableStateMapOf<String, Any>()

    var 规则名称 by mutableStateOf("")
    var 规则地址 by mutableStateOf("")
    var 规则协议头 by mutableStateOf("")
    var 规则类型 by mutableStateOf(快照类型枚举.列表)
    val database by lazy { GlobalContext.get().get<AppDatabase>() }


    suspend fun 加载(){
        if (mEditId != 0L) {
            val db = database.快照().查询规则ById(mEditId)
            db?.let {
                规则名称 = it.名称
                规则地址 = it.匹配地址
                规则类型 = it.类型


                // 反序列化规则内容到编辑数据
                try {
                    val map = Gson().fromJson(it.规则内容, Map::class.java) as Map<String, Any>
                    if (map.containsKey("header")){
                        规则协议头 = map.getOrDefault("header","").toString()
                    }

                    编辑数据.clear()
                    编辑数据.putAll(map)
                } catch (e: Exception) {
                    e.printStackTrace()
                    mlog("规则内容反序列化失败", e)
                }
            }
        }
    }
    fun 保存(){
        coroutine?.launch() {
            withContext(Dispatchers.IO) {

                编辑数据.put("header", 规则协议头)
                编辑数据.put("type", 规则类型.name)
                编辑数据.put("url", 规则地址)
                编辑数据.put("name", 规则名称)

                // 组装 DBQzm
                val db = DBQzm(
                    id = mEditId,
                    bid = bid,
                    名称 = 规则名称,
                    匹配地址 = 规则地址,
                    类型 = 规则类型,
                    规则内容 = GsonUtils.toJson(编辑数据),
                    启用 = true
                )
                mlog("规则",GsonUtils.toJson(编辑数据))

                if (mEditId == 0L) {
                    val id = database.快照().插入规则(db)
                    db.id = id
                } else {
                    database.快照().更新规则(db)
                }

            }
        }
    }
    fun 删除(){
        coroutine?.launch {
            withContext(Dispatchers.IO) {
                val db = database.快照().查询规则ById(mEditId)
                if (db != null) {
                    database.快照().删除规则(db)
                }
            }
        }
    }


}

@Composable
fun 快照编辑页面实现(state : 快照编辑页面状态){
    state.coroutine = rememberCoroutineScope()
    DisposableEffect (Unit) {
        onDispose {
            state.coroutine = null
        }
    }
    LaunchedEffect(Unit) {
        state.加载()
    }

    var 显示更多操作  by remember { mutableStateOf(false) }
    统一标签页布局(
        title = { if (state.mEditId == 0L) "创建快照规则" else "编辑快照规则" },
        action = {
            IconButton({state.保存()}) {
                Icon(MyIconPack.保存,"")
            }
            IconButton({显示更多操作 = true}) {
                Icon(MyIconPack.更多,"")
                下拉菜单(显示更多操作,{显示更多操作 = false}){
                    下拉菜单项目("删除规则"){
                        state.删除()
                    }
                }
            }
        })
    {

        LazyColumn(Modifier.weight(1f)){

            // 基本信息
            item {
                项目卡片 {
                    基本信息(state)
                }
            }

            item {
                项目卡片 {
                    配置列表(state)
                }

            }

            item{
                Spacer(Modifier.height(30.dp)
                    .windowInsetsBottomHeight(WindowInsets.ime))
            }
        }


    }

}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun 基本信息(state: 快照编辑页面状态){
    OutlinedTextField(
        value = state.规则名称,
        onValueChange = { state.规则名称 = it },
        label = { Text("name - 快照名称") },
        modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
    )

    OutlinedTextField(
        value = state.规则地址,
        onValueChange = { state.规则地址 = it },
        label = { Text("url - 快照匹配的地址(正则)") },
        modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
    )

    OutlinedTextField(
        value = state.规则协议头,
        onValueChange = { state.规则协议头 = it },
        label = { Text("header -协议头（访问地址时额外的协议头）") },
        modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
    )

    var showEnum by remember { mutableStateOf(false) }
    ExposedDropdownMenuBox(
        expanded = showEnum,
        onExpandedChange = { showEnum = !showEnum },
    ) {
        OutlinedTextField(state.规则类型.name, onValueChange = {}, label = { Text("类型") },
            trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = showEnum) },
            readOnly = true,
            modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
                .menuAnchor()
                .clickable() {showEnum = true})
        下拉菜单(showEnum,{showEnum = false}){
            快照类型枚举.entries.forEach {
                下拉菜单项目(it.name){
                    state.规则类型 = it
                    showEnum = false
                }
            }
        }
    }



}

@Composable
private fun 配置列表(state: 快照编辑页面状态){
    var clazz : KClass<out 快照来源接口> = when(state.规则类型){
        快照类型枚举.列表 -> 快照源_列表::class
        快照类型枚举.章节列表 -> cn.mujiankeji.mbrowser.数据.快照来源.快照源_章节列表::class
        快照类型枚举.视频 -> cn.mujiankeji.mbrowser.数据.快照来源.快照源_视频::class
        快照类型枚举.阅读 -> cn.mujiankeji.mbrowser.数据.快照来源.快照源_阅读::class
    }

    var props : List<kotlin.reflect.KProperty1<Any, *>> = clazz.members.filterIsInstance<kotlin.reflect.KProperty1<Any, *>>()
        .filter { it.visibility == kotlin.reflect.KVisibility.PUBLIC }
        .filter { it.parameters.size == 1 }

    // 初始化编辑数据
    LaunchedEffect(state.规则类型) {

        val new = mutableMapOf<String, Any>()
        props.forEach { prop ->
            val key = (prop.findAnnotations(SerialName::class).firstOrNull()?.value) ?:""
            val defaultValue = when (prop.returnType.classifier) {
                String::class -> ""
                Boolean::class -> false
                else -> null
            }
            (state.编辑数据.get(key) ?: defaultValue)?.let { new[key] = it }

        }
        state.编辑数据.clear()
        state.编辑数据.putAll(new)
        mlog("aa",new)
    }

    Column {
        props.forEach { prop ->
            val key = (prop.findAnnotations(SerialName::class).firstOrNull()?.value) ?:""
            val varName = prop.name
            val value = state.编辑数据[varName]

            when(key){
                "url","title","header"->{
                    // mlog("key",key,varName,value)
                }
                else ->{
                    when (prop.returnType.classifier) {
                        String::class -> {
                            mlog("str",key,varName,state.编辑数据[key.ifEmpty { varName }]?:"")
                            OutlinedTextField((state.编辑数据[key.ifEmpty { varName }]?:"").toString(), onValueChange = {
                                state.编辑数据[key.ifEmpty { varName }] = it
                            }, label = { Text(key + " - ${varName}") },
                                modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp))
                        }
                        Boolean::class -> {
                            配置行_开关(key, value as? Boolean ?: false) { newValue ->
                                state.编辑数据[prop.name] = newValue
                            }
                        }
                        else -> {
                            mlog("未知类型",prop.returnType.classifier)
                            // 其他类型可忽略或自定义
                        }
                    }
                }
            }

        }

    }


}